<template>
  <div class="design-canvas-container">
    <canvas ref="canvas" class="design-canvas"></canvas>
  </div>
</template>

<script>
import { fabric } from 'fabric';
import { debounce } from 'lodash';
import { CanvasTexture } from 'three';
import {mapState} from "vuex";

export default {
  name: 'DesignCanvas',
  props: {
    onCanvasUpdate: {
      type: Function,
      default: () => {}
    },
    vectorData: {
      type: String,
      default: ''
    }
  },
  data() {
    return {
      fabricCanvas: null,
      isCanvasReady: false,
      isDesignLoaded: false,
      storedPositions: new Map(),
      isEditing: false,
      controls: {
        addText: this.addText,
        addImage: this.addImage,
        handleInteraction: this.handleInteraction,
        updateObject: this.updateObject,
        deleteObject: this.deleteObject,
        recreateFromProperties: this.recreateFromProperties,
        loadVectorData: this.loadVectorData,
        canvas: null
      }
    };
  },
  computed: {
    selectedDesignPath() {
      return this.$store.getters['designs/selectedDesign']?.path || '';
    },
    pathColors() {
      return this.$store.state.colors.pathColors || [];
    },
    decorations() {
      return this.$store.state.decorations.items || [];
    },
    ...mapState('colors', ['selectColor', 'selectFont']),
  },
  mounted() {
    this.initializeCanvas();
  },
  beforeDestroy() {
    if (this.fabricCanvas) {
      this.fabricCanvas.dispose();
      this.fabricCanvas = null;
    }
  },
  methods: {
    // 初始化Fabric画布
    initializeCanvas() {
      if (!this.$refs.canvas) return;

      const containerWidth = this.$el.clientWidth;
      const containerHeight = this.$el.clientHeight;
      const size = Math.min(containerWidth, containerHeight) - 32;

      this.$refs.canvas.width = size;
      this.$refs.canvas.height = size;

      this.fabricCanvas = new fabric.Canvas(this.$refs.canvas, {
        width: size,
        height: size,
        backgroundColor: '#ffffff',
        preserveObjectStacking: true,
        uniformScaling: true,
        stopContextMenu: true
      });

      this.setupCanvasEvents();
      this.controls.canvas = this.fabricCanvas;
      this.$emit('init', this.controls);

      this.isCanvasReady = true;

      if (this.selectedDesignPath) {
        this.loadDesign(this.selectedDesignPath).then(() => {
          this.decorations.forEach(decoration => {
            this.recreateFromProperties(decoration.type, {
              ...decoration.properties,
              id: decoration.id
            });
          });
          this.renderCanvas();
        });
      }
    },

    // 设置画布事件
    setupCanvasEvents() {
      const canvas = this.fabricCanvas;
      console.log('668', canvas)

      canvas.on('mouse:dblclick', () => false);

      const events = [
        'object:modified',
        'object:added',
        'object:removed',
        'object:moving',
        'object:scaling',
        'object:rotating',
        'object:skewing',
        'text:changed',
        'canvas:cleared'
      ];

      canvas.on('selection:created', (e) => {
        console.log(777)
        this.isEditing = true;
        this.controls.onSelectionChange?.(true);
        this.controls.onObjectSelected?.(canvas.getActiveObject());
        this.renderCanvas();
        console.log('Started editing text:', e.target?.id);
      });

      canvas.on('selection:updated', (e) => {
        if (e.deselected && e.deselected[0]) {
          this.saveObjectPosition(e.deselected[0]);
        }
        this.controls.onSelectionChange?.(true);
        this.controls.onObjectSelected?.(canvas.getActiveObject());
        this.renderCanvas();
      });

      canvas.on('selection:cleared', (e) => {
        if (this.isEditing && e.deselected?.[0]) {
          this.saveObjectPosition(e.deselected[0]);
        }

        this.isEditing = false;
        this.controls.onSelectionChange?.(false);
        this.controls.onObjectSelected?.(null);
        this.renderCanvas();
      });

      events.forEach(eventName => {
        canvas.on(eventName, this.renderCanvas);
      });

      // 拖拽相关事件
      let isDragging = false;

      canvas.on({
        'mouse:down': (e) => {
          console.log('899', e.target.type)
          const target = e.target;
          if (target && (target.type === 'i-text' || target.type === 'image')) {
            isDragging = true;
            e.e.preventDefault();
            e.e.stopPropagation();
            this.controls.onDragStart();
          }
        },
        'object:moving': (e) => {
          if (isDragging) {
            e.e.preventDefault();
            e.e.stopPropagation();
            this.handleModification(e);
            this.handleInteraction(e);
          }
        },
        'mouse:up': (e) => {
          if (isDragging) {
            isDragging = false;
            e.e.preventDefault();
            e.e.stopPropagation();
            this.controls.onDragEnd?.();
            this.renderCanvas();
            this.updateTexture();
          }
        },
        'selection:cleared': () => {
          if (isDragging) {
            isDragging = false;
            this.controls.onDragEnd?.();
            this.renderCanvas();
            this.updateTexture();
          }
        }
      });

      canvas.on('mouse:up', () => {
        this.debouncedTextureUpdate.flush();
        this.updateTexture();
      });
    },

    // 加载设计
    loadDesign(path) {
      console.log('1. Starting loadDesign with path:', path);
      return new Promise((resolve) => {
        this.fabricCanvas.clear();

        fabric.loadSVGFromURL(path, (objects, options) => {
          if (objects && objects.length > 0) {
            const colorableObjects = objects.filter(obj =>
                (obj.type === 'path' || obj.type === 'rect') &&
                obj.fill &&
                typeof obj.fill === 'string'
            );

            if (this.pathColors.length === 0 || colorableObjects.length !== this.pathColors.length) {
              const colors = colorableObjects.map((obj, index) => ({
                id: `path-${index}`,
                name: `Path ${index + 1}`,
                fill: obj.fill || '#000000'
              }));
              this.$store.dispatch('colors/setPathColors', colors);
            }
          }

          if (!objects || objects.length === 0) {
            resolve();
            return;
          }

          const design = fabric.util.groupSVGElements(objects, options);
          design.set({
            left: 0,
            top: 0,
            selectable: false,
            evented: false,
            data: { isBackground: true }
          });

          const scaleX = this.fabricCanvas.width / design.width;
          const scaleY = this.fabricCanvas.height / design.height;
          const scale = Math.min(scaleX, scaleY);

          design.scale(scale);
          design.center();

          this.fabricCanvas.add(design);
          this.fabricCanvas.sendToBack(design);
          this.applyColors(design);

          this.renderCanvas();
          this.isDesignLoaded = true;
          resolve();
        });
      });
    },

    // 应用颜色
    applyColors(design) {
      if (!design || !design.getObjects) return;

      const paths = design.getObjects();
      if (!paths || paths.length === 0) return;

      paths.forEach((path, index) => {
        const pathId = `path-${index}`;
        const color = this.pathColors.find(c => c.id === pathId);
        if (color) {
          path.set('fill', color.fill);
        }
      });

      this.renderCanvas();
    },

    // 加载矢量数据
    loadVectorData(data) {
      if (!this.fabricCanvas || !this.isDesignLoaded) return;

      try {
        const jsonData = JSON.parse(data);
        const existingObjects = new Map();

        // 移除非背景对象
        const objects = this.fabricCanvas.getObjects();
        objects.forEach(obj => {
          if (!obj.data?.isBackground) {
            this.fabricCanvas.remove(obj);
          }
        });

        this.fabricCanvas.loadFromJSON(jsonData, () => {
          this.fabricCanvas.getObjects().forEach(obj => {
            if (!obj.data?.isBackground) {
              if (obj.id && existingObjects.has(obj.id)) {
                this.fabricCanvas.remove(obj);
                return;
              }

              obj.set({
                lockSkewingX: true,
                lockSkewingY: true,
                centeredScaling: true,
                snapAngle: 5,
                cornerStyle: 'circle',
                transparentCorners: false,
                cornerColor: '#1976D2',
                cornerSize: 10,
                padding: 10,
                borderColor: '#1976D2',
                borderScaleFactor: 2,
                opacity: obj.opacity || 1
              });

              if (obj.type === 'i-text') {
                obj.set({ editable: false });
              }

              if (obj.id) {
                existingObjects.set(obj.id, obj);
              }
            }
          });

          // 添加新装饰到状态
          this.fabricCanvas.getObjects().forEach(obj => {
            if (!obj.data?.isBackground && obj.id) {
              const decoration = this.decorations.find(d => d.id === obj.id);
              if (!decoration) {
                this.controls.onObjectAdded?.(obj);
              }
            }
          });

          this.renderCanvas();
        });
      } catch (error) {
        console.error('Error loading vector data:', error);
      }
    },

    // 添加文本
    addText(position = { x: 0.5, y: 0.5 }) {
      if (!this.fabricCanvas) return;

      const text = new fabric.IText('Edit Text', {
        left: position.x * this.fabricCanvas.width,
        top: position.y * this.fabricCanvas.height,
        fontSize: 24,
        fontFamily: this.selectFont[0] || 'Arial',
        fill: this.selectColor[0].hex || '#000000',
        editable: true,
        lockSkewingX: true,
        lockSkewingY: true,
        centeredScaling: true,
        scaleX: 0.5,
        scaleY: 0.5,
        snapAngle: 5,
        cornerStyle: 'circle',
        transparentCorners: false,
        cornerColor: '#1976D2',
        cornerSize: 10,
        padding: 10,
        borderColor: '#1976D2',
        borderScaleFactor: 2
      });

      this.fabricCanvas.add(text);
      this.fabricCanvas.setActiveObject(text);
      this.renderCanvas();
      this.controls.onObjectAdded?.(text);
    },

    // 添加图片
    addImage(file, position = { x: 0.5, y: 0.5 }) {
      return new Promise((resolve) => {
        const reader = new FileReader();
        reader.onload = (e) => {
          const img = new Image();
          img.onload = () => {
            const fabricImage = new fabric.Image(img, {
              left: position.x * this.fabricCanvas.width,
              top: position.y * this.fabricCanvas.height,
              lockSkewingX: true,
              lockSkewingY: true,
              centeredScaling: true,
              snapAngle: 5,
              cornerStyle: 'circle',
              transparentCorners: false,
              cornerColor: '#1976D2',
              cornerSize: 10,
              padding: 10,
              borderColor: '#1976D2',
              borderScaleFactor: 2
            });

            fabricImage.scaleToWidth(50);
            this.fabricCanvas.add(fabricImage);
            this.fabricCanvas.setActiveObject(fabricImage);
            this.controls.onObjectAdded?.(fabricImage);
            this.renderCanvas();
            resolve(fabricImage);
          };
          img.src = e.target.result;
        };
        reader.readAsDataURL(file);
      });
    },

    // 处理交互
    handleInteraction(point) {
      if (!this.fabricCanvas) return;

      const width = this.fabricCanvas.width;
      const height = this.fabricCanvas.height;

      const canvasX = point.x * width;
      const canvasY = point.y * height;

      const rect = this.fabricCanvas.getElement().getBoundingClientRect();

      const fabricEvent = {
        clientX: rect.left + canvasX,
        clientY: rect.top + canvasY,
        target: this.fabricCanvas.getElement(),
        preventDefault: () => {},
        stopPropagation: () => {},
        type: point.type,
        offsetX: canvasX,
        offsetY: canvasY,
        which: 1
      };

      if (point.type === 'mousedown') {
        const target = this.fabricCanvas.findTarget(fabricEvent);
        if (target) {
          if (target !== this.fabricCanvas.getActiveObject()) {
            this.fabricCanvas.setActiveObject(target);
            this.controls.onSelectionChange?.(true);
          }
          this.fabricCanvas.__onMouseDown(fabricEvent);
        } else {
          this.fabricCanvas.discardActiveObject();
          this.controls.onSelectionChange?.(false);
        }
      } else if (point.type === 'mousemove') {
        if (this.fabricCanvas.getActiveObject()) {
          this.controls.onSelectionChange?.(true);
        }
        this.fabricCanvas.__onMouseMove(fabricEvent);
      } else if (point.type === 'mouseup') {
        if (this.fabricCanvas.getActiveObject()) {
          this.controls.onSelectionChange?.(true);
        }
        this.fabricCanvas.__onMouseUp(fabricEvent);
      }

      this.renderCanvas();
    },

    // 更新对象
    updateObject(updates) {
      if (!this.fabricCanvas) return;

      if (updates === null) {
        this.fabricCanvas.discardActiveObject();
        this.renderCanvas();
        return;
      }

      const activeObject = this.fabricCanvas.getActiveObject();
      if (activeObject) {
        if (updates.text !== undefined && activeObject.type === 'i-text') {
          activeObject.text = updates.text;
        }
        activeObject.set(updates);
        this.renderCanvas();
      }
    },

    // 删除对象
    deleteObject(object) {
      if (!this.fabricCanvas) return;

      this.fabricCanvas.remove(object);
      this.controls.onObjectRemoved?.(object);
      this.renderCanvas();
    },

    // 从属性重新创建对象
    recreateFromProperties(type, properties) {
      if (!this.fabricCanvas) return;

      const existingObject = this.fabricCanvas.getObjects().find(obj => obj.id === properties.id);
      if (existingObject) {
        existingObject.set({
          left: properties.left,
          top: properties.top,
          scaleX: properties.scaleX,
          scaleY: properties.scaleY,
          angle: properties.angle,
          opacity: properties.opacity || 1,
          ...(type === 'text' ? {
            text: properties.text,
            fontFamily: properties.fontFamily,
            fill: properties.fill,
            strokeWidth: properties.strokeWidth,
            stroke: properties.stroke
          } : {})
        });
        this.renderCanvas();
        return;
      }

      const commonProps = {
        id: properties.id,
        left: properties.left,
        top: properties.top,
        scaleX: properties.scaleX,
        scaleY: properties.scaleY,
        angle: properties.angle,
        opacity: properties.opacity || 1,
        editable: false,
        lockSkewingX: true,
        lockSkewingY: true,
        centeredScaling: true,
        snapAngle: 5,
        cornerStyle: 'circle',
        transparentCorners: false,
        cornerColor: '#1976D2',
        cornerSize: 10,
        padding: 10,
        borderColor: '#1976D2',
        borderScaleFactor: 2
      };

      if (type === 'text') {
        const text = new fabric.IText(properties.text || 'Text', {
          ...commonProps,
          fontFamily: properties.fontFamily,
          fill: properties.fill,
          strokeWidth: properties.strokeWidth,
          stroke: properties.stroke
        });

        this.fabricCanvas.add(text);
        this.renderCanvas();
      } else if (type === 'image') {
        fabric.Image.fromURL(properties.src, (img) => {
          img.set(commonProps);
          this.fabricCanvas.add(img);
          this.renderCanvas();
        });
      }
    },

    // 保存对象位置
    saveObjectPosition(obj) {
      if (!obj || !obj.id) return;

      const finalPosition = {
        left: obj.left,
        top: obj.top,
        scaleX: obj.scaleX,
        scaleY: obj.scaleY,
        angle: obj.angle
      };

      this.storedPositions.set(obj.id, finalPosition);

      let properties;
      if (obj.type === 'i-text') {
        properties = {
          ...finalPosition,
          text: obj.text,
          fontFamily: obj.fontFamily,
          fill: obj.fill
        };
      } else {
        properties = {
          ...finalPosition,
          src: obj.getSrc()
        };
      }

      this.$store.dispatch('decorations/updateDecoration', {
        id: obj.id,
        properties
      });
    },

    // 处理对象修改
    handleModification(e) {
      if (!e.target) return;

      if (e.target.type === 'i-text' || e.target.type === 'image') {
        if (!this.isEditing) {
          const storedPosition = this.storedPositions.get(e.target.id);
          if (storedPosition) {
            e.target.set(storedPosition);
            this.renderCanvas();
          }
        }

        this.updateObjectState(e.target);
        this.renderCanvas();
        this.debouncedTextureUpdate(this.fabricCanvas);
      }
    },

    // 更新对象状态
    updateObjectState(obj) {
      if (!obj || !obj.id) return;

      const currentState = {
        left: obj.left,
        top: obj.top,
        scaleX: obj.scaleX,
        scaleY: obj.scaleY,
        angle: obj.angle,
        opacity: obj.opacity,
        ...(obj.type === 'i-text' ? {
          text: obj.text,
          fontFamily: obj.fontFamily,
          fill: obj.fill,
          strokeWidth: obj.strokeWidth,
          stroke: obj.stroke
        } : {
          src: obj.getSrc()
        })
      };

      Object.keys(currentState).forEach(key => {
        if (currentState[key] === undefined) {
          delete currentState[key];
        }
      });

      this.$store.dispatch('decorations/updateDecoration', {
        id: obj.id,
        properties: currentState
      });
    },

    // 渲染画布
    renderCanvas() {
      if (this.fabricCanvas) {
        this.fabricCanvas.renderAll();
        this.updateTexture();
      }
    },

    // 更新纹理（防抖）
    debouncedTextureUpdate: debounce(function(canvas) {
      if (!canvas?.getElement()) return;

      window.requestAnimationFrame(() => {
        try {
          const texture = new CanvasTexture(canvas.getElement());
          texture.needsUpdate = true;
          this.$emit('canvas-update', texture);
        } catch (error) {
          console.error('Error updating texture:', error);
        }
      });
    }, 100),

    // 更新纹理
    updateTexture() {
      this.debouncedTextureUpdate(this.fabricCanvas);
    }
  },
  watch: {
    pathColors: {
      handler() {
        if (this.fabricCanvas && this.isDesignLoaded) {
          const design = this.fabricCanvas.getObjects().find(obj => obj.data?.isBackground);
          if (design && design.type === 'group') {
            this.applyColors(design);
          }
        }
      },
      deep: true
    },
    vectorData: {
      handler(newVal) {
        if (newVal && this.isCanvasReady && this.isDesignLoaded) {
          this.loadVectorData(newVal);
        }
      },
      immediate: true
    },
    selectedDesignPath: {
      handler(newVal) {
        if (newVal) {
          this.initializeCanvas(newVal);
        }
      },
    },
    decorations: {
      handler(newVal) {
        if (newVal) {
          this.loadDesign(this.selectedDesignPath).then(() => {
            newVal.forEach(decoration => {
              this.recreateFromProperties(decoration.type, {
                ...decoration.properties,
                id: decoration.id
              });
            });
            this.renderCanvas();
          });
        }
      },
    }
  }
};
</script>

<style scoped>
.design-canvas-container {
  width: 100%;
  height: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 1rem;
}

.design-canvas {
  max-width: 100%;
  max-height: 100%;
  box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
}
</style>
